﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using MagicKey.Components.Database;
using MagicKey.Components.UserManager;
using MagicKey.Factory;
using MagicKey.Interfaces;

namespace MagicKey.UserInterface
{
    /// <summary>
    ///     Interaktionslogik für Rechteverwalten.xaml
    /// </summary>
    public partial class ManageAuthorizations : Window
    {
        #region Fields

        private readonly IAccessManager _accessManager = MagicKeyFactory.GetInstance().GetMagicKeyInterface().GetAccessManager();
        private readonly IUserManager _userManager = MagicKeyFactory.GetInstance().GetMagicKeyInterface().GetUserManager();
        private readonly IFileAccess _fileAccess = MagicKeyFactory.GetInstance().GetMagicKeyInterface().GetFileAccess();

        private readonly User _masterUser;
        private readonly string _selectedFile;
        private readonly List<User> _allUsers;
        
        private bool _saved = true;
        private List<string> _usersWithAuth;
        private List<string> _usersWithoutAuth;
        private User _currentRecipient;

        #endregion

        #region Constructor

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileviewer"></param>
        public ManageAuthorizations(Fileviewer fileviewer)
        {
            InitializeComponent();

            // The following line enables the tremble effect for the current
            // window when clicking on the main window
            Owner = fileviewer;

            _selectedFile = (string)fileviewer.FileListBox.SelectedItem;

            // allUsers = fileviewer.AllUsers;
            _userManager.LoadAllUsers();
            _allUsers = ((UserManager)_userManager).Users;

            _masterUser = fileviewer.MasterUser;
            _usersWithoutAuth = new List<string>();
            _usersWithAuth = new List<string>();
            Init();
        }

        #endregion

        #region Methods

        /// <summary>
        /// 
        /// </summary>
        public void Init()
        {
            CurrentFileLabel.Content += " " + _selectedFile;

            foreach (User u in _allUsers)
            {
                if (u.OtherUserFiles.Contains(_selectedFile))
                {
                    _usersWithAuth.Add(u.Name);
                }
                else
                {
                    _usersWithoutAuth.Add(u.Name);
                }
            }

            try
            {
                _usersWithAuth.Remove(_masterUser.Name);
                _usersWithoutAuth.Remove(_masterUser.Name);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            RefreshfileList();
        }

        private void RefreshfileList()
        {
            ListUserWithAuthorizationBox.ItemsSource = _usersWithAuth;
            ListUserNoAuthorizationBox.ItemsSource = _usersWithoutAuth;
        }

        #endregion

        #region EventChangedMethods

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddAuthorization_Click(object sender, RoutedEventArgs e)
        {
            List<string> usersWithoutAuth = _usersWithoutAuth.ToList();

            List<string> usersWithAuth = _usersWithAuth.ToList();

            if (ListUserNoAuthorizationBox.SelectedIndex != -1)
            {
                int selectedIndex = ListUserNoAuthorizationBox.SelectedIndex;
                var selectedUser = (string)ListUserNoAuthorizationBox.SelectedItem;

                _usersWithAuth = null;
                _usersWithoutAuth = null;

                usersWithAuth.Add(selectedUser);
                usersWithoutAuth.RemoveAt(selectedIndex);

                _usersWithAuth = usersWithAuth;
                _usersWithoutAuth = usersWithoutAuth;

                RefreshfileList();
            }
            else
            {
                MessageBox.Show("Please select one user to add!", "Authorization",
                    MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddAuthorizationToAll_Click(object sender, RoutedEventArgs e)
        {
            int count = ListUserNoAuthorizationBox.Items.Count;
            if (count != 0)
            {
                const string msg = "Do you really want to add all users?";
                MessageBoxResult result = MessageBox.Show(msg, "Manage authorizations",
                    MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.Yes)
                {
                    var usersWithoutAuth = new List<string>();
                    List<string> usersWithAuth = _usersWithAuth.ToList();
                    usersWithAuth.AddRange(_usersWithoutAuth);


                    _usersWithAuth = null;
                    _usersWithoutAuth = null;

                    _usersWithAuth = usersWithAuth;
                    _usersWithoutAuth = usersWithoutAuth;

                    RefreshfileList();
                }
            }
            else if (count == 1)
            {
                AddAuthorization_Click(sender, new RoutedEventArgs());
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RemoveAuthorization_Click(object sender, RoutedEventArgs e)
        {
            var usersWithoutAuth = _usersWithoutAuth.ToList();

            var usersWithAuth = _usersWithAuth.ToList();

            if (ListUserWithAuthorizationBox.SelectedIndex != -1)
            {
                int selectedIndex = ListUserWithAuthorizationBox.SelectedIndex;
                var selectedUser = (string)ListUserWithAuthorizationBox.SelectedItem;

                _usersWithAuth = null;
                _usersWithoutAuth = null;

                usersWithoutAuth.Add(selectedUser);
                usersWithAuth.RemoveAt(selectedIndex);

                _usersWithAuth = usersWithAuth;
                _usersWithoutAuth = usersWithoutAuth;

                RefreshfileList();
            }
            else
            {
                MessageBox.Show("Please select one user to remove!", "Authorization",
                    MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RemoveAuthorizationToAll_Click(object sender, RoutedEventArgs e)
        {
            int count = ListUserWithAuthorizationBox.Items.Count;
            if (count != 0)
            {
                string msg = "Do you really want to remove all users?";
                MessageBoxResult result = MessageBox.Show(msg, "Manage authorizations",
                    MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.Yes)
                {
                    var usersWithAuth = new List<string>();

                    var usersWithoutAuth = _usersWithoutAuth.ToList();
                    usersWithoutAuth.AddRange(_usersWithAuth);


                    _usersWithAuth = null;
                    _usersWithoutAuth = null;

                    _usersWithAuth = usersWithAuth;
                    _usersWithoutAuth = usersWithoutAuth;

                    RefreshfileList();
                }
            }
            else if (count == 1)
            {
                RemoveAuthorization_Click(sender, new RoutedEventArgs());
            }
        }


        private void ListUserNoAuthorizationBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //set a current user
            _currentRecipient = null;
        }

        private void ListUserWithAuthorizationBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
        }


        private void Save_Click(object sender, RoutedEventArgs e)
        {
            var listUserId = new List<int>();
            var listUserIdToRemove = new List<int>();

           
            int fileId = _userManager.GetFileId(_selectedFile);

            foreach (string s in _usersWithAuth)
            {
                foreach (User u in _allUsers)
                {
                    if (u.Name.Equals(s))
                    {
                        listUserId.Add(u.Id);
                        break;
                    }
                }
            }

            foreach (string s in _usersWithoutAuth)
            {
                foreach (User u in _allUsers)
                {
                    if (u.Name.Equals(s))
                    {
                        listUserIdToRemove.Add(u.Id);
                        break;
                    }
                }
            }

            int index = 0;
            foreach (int i in listUserId)
            {
                //string recipientName = _currentRecipient.Name;
                string recipientName = _usersWithAuth[index++];

                // master symetric key
                var masterSymetricKey1 = _userManager.GetUserSymetricKey(this._masterUser.Name.ToLower());
                var key = _masterUser.Role;
                var masterSymetricKey = _accessManager.DecryptStringSym(masterSymetricKey1, key);
                key = null;
                
                // recipient public key
                var recipientPublicKey = _userManager.GetPublicKey(recipientName);

                //
                var encryptedSymetricKeyOfRecipient = _accessManager.EncryptStringAsym(recipientPublicKey, masterSymetricKey);

                // recipient public key
                var senderPublicKey = _userManager.GetPublicKey(this._masterUser.Name.ToLower());

                //
                var encryptedSymetricKeyOfSender = _accessManager.EncryptStringAsym(senderPublicKey, masterSymetricKey);
                masterSymetricKey = null;
                _accessManager.InsertAuthorisationAccess(this._masterUser.Id, i, fileId,encryptedSymetricKeyOfRecipient,encryptedSymetricKeyOfSender);
            }

            foreach (int i in listUserIdToRemove)
            {
                _accessManager.RemoveAuthorization(i);
            }
            RefreshfileList();
            _saved = false;
            Close();
        }

        ///
        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void ManageAuthorizations_OnClosing(object sender, CancelEventArgs e)
        {
            if (_saved)
            {
                string msg = "Do you really want to cancel?";
                MessageBoxResult result = MessageBox.Show(msg, "Manage authorizations",
                    MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.No)
                {
                    // If user doesn't want to close, cancel closure
                    ((Fileviewer)Owner).RefreshfileList();
                    e.Cancel = true;
                }
                else
                {
                    Owner.Focus();
                    e.Cancel = false;
                }
            }
            else
            {
                MessageBox.Show("Saving was successfull.", "Manage authorizations",
                    MessageBoxButton.OK, MessageBoxImage.Information);
                Owner.Focus();
                e.Cancel = false;
            }
        }

        private void ListUserNoAuthorizationBox_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            AddAuthorization_Click(sender, new RoutedEventArgs());
        }

        private void ListUserWithAuthorizationBox_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            RemoveAuthorization_Click(sender, new RoutedEventArgs());
        }

        #endregion
    }
}